<?php

namespace App\Services;

use App\Common\Libs\ArrayHelper;
use App\Common\Libs\Dispatch\Queue;
use App\Common\Libs\HttpClient;
use App\Consts\GlobalConst;
use App\Consts\GlobalLoginConst;
use App\Consts\GlobalQueueConst;
use App\Exceptions\Error;
use App\Formats\RecommendSystemFormat;
use App\Jobs\Controller\RecommendSystemJob;

class RecommendSystemService extends BaseService
{
    /**
     * 获取推荐列表
     * @param $searchParams
     * @return \Illuminate\Http\JsonResponse|array
     */
    public function getRecommendList($searchParams)
    {
        $searchParams = ArrayHelper::merge($searchParams, [
            'from' => 'web',
        ]);

        // 走【李世泉】接口，获取并格式化推荐结果
        $recommendSystemResult = $this->getRecommendData($searchParams);
        if (!$recommendSystemResult) {
            return Error::handle(lang('recommend url is invalid'));
        }
        $recommendData = $this->formatRecommendData($recommendSystemResult);

        // 格式化结果，此时是乱序的
        $recommendList = formats()->RecommendSystemFormat->formatRecommendSystemList($recommendData, $searchParams['current_user_id'], RecommendSystemFormat::SQUARE_RECOMMEND_LIST);

        // 按照推荐结果中的顺序进行排序
        $sortedRecommendList = $this->reSotrRecommendList($recommendData, $recommendList);

        return [
            'have_more' => $recommendSystemResult['data']['has_next'],
            'list' => $sortedRecommendList,
        ];
    }

    /**
     * 获取推荐系统数据
     * @param $params
     * @return mixed
     */
    public function getRecommendData($params)
    {

        $url = service()->ConfigService->getConfigByKey('recommendUrl');
        $recommendList = HttpClient::getInstance()->post($url, $params);
        if (!is_array($recommendList) || !isset($recommendList['data']['list'])) {
            return false;
        }

        return $recommendList;
    }

    /**
     * 按类别格式化推荐系统数据
     * @param $recommendList
     * @return array[]
     */
    public function formatRecommendData($recommendList)
    {
        $articleIdArr = [];
        $noteIdArr = [];

        foreach ($recommendList['data']['list'] as $item) {
            if (in_array(
                $item['target_type'],
                [GlobalConst::NEW_TARGET_TYPE_QUICK_RECOMMEND_ARTICLE, GlobalConst::NEW_TARGET_TYPE_ORIGINAL_ARTICLE]
            )) {
                $articleIdArr[] = $item['target_id'];
            }

            if (in_array(
                $item['target_type'],
                [GlobalConst::NEW_TARGET_TYPE_LINE_NOTE, GlobalConst::NEW_TARGET_TYPE_ARTICLE_NOTE]
            )) {
                $noteIdArr[] = $item['target_id'];
            }
        }

        return [
            'article' => $articleIdArr,
            'note' => $noteIdArr,
        ];
    }

    /**
     * 按照推荐结果中的顺序进行排序
     * @param $recommendData
     * @param $recommendList
     * @return array
     */
    public function reSotrRecommendList($recommendData, $recommendList)
    {
        // 按照推荐顺序
        $list = ArrayHelper::index($recommendList, 'id');
        $result = [];
        foreach ($recommendData as $targetIdArr) {
            foreach ($targetIdArr as $targetId) {
                if (!empty($list[$targetId])) {
                    $result[] = $list[$targetId];
                }
            }
        }

        return $result;
    }

    /**
     * 推送【内容】到推荐系统
     * @param $params
     * @return \Illuminate\Foundation\Bus\PendingDispatch
     */
    public function addTarget($params)
    {
        return Queue::getInstance(RecommendSystemJob::class)
            ->push($params, GlobalQueueConst::RECOMMEND_SYSTEM_ADD_TARGET);
    }

    /**
     * 推送【浏览记录】到推荐系统
     * @param $params
     * @return \Illuminate\Foundation\Bus\PendingDispatch
     */
    public function addView($params)
    {
        return Queue::getInstance(RecommendSystemJob::class)
            ->push($params, GlobalQueueConst::RECOMMEND_SYSTEM_ADD_VIEW);
    }

    /**
     * 从推荐系统移除
     * @param $params
     * @return \Illuminate\Foundation\Bus\PendingDispatch
     */
    public function remove($params)
    {
        return Queue::getInstance(RecommendSystemJob::class)
            ->push($params, GlobalQueueConst::RECOMMEND_SYSTEM_REMOVE);
    }
}
